/*
 * Conf.cpp
 *
 *  Created on: Aug 12, 2016
 *      Author: ubuntu
 */

#include "Conf.h"

#include "common.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libconfig.h++>

using namespace std;
using namespace libconfig;

static Conf conf;

Conf *getConf()
{
	return &conf;
}

void ConfInit()
{
	conf.start = time(NULL);
	conf.path = NULL;
	conf.cpool = NULL;
	conf.n900_file = NULL;
	conf.m_n900_version = 0;
	conf.g2o_file = NULL;
	conf.m_g2o_version = 0;
	conf.mtime = 0;
	conf.unix_path = NULL;
	conf.pManager = NULL;
}

const char *ConfFile()
{
	return conf.path;
}

void SetConf(const char *filename)
{
	if (conf.path)
		free(conf.path);
	conf.path = strdup(filename);
	if (!conf.path)
	{
		printf("设置配置文件错误，退出\n");
		exit(-1);
	}
	struct stat buf;
	if (stat(conf.path, &buf) < 0) {
		perror("stat");
		exit(-1);
	}
	conf.mtime = buf.st_mtime;
}

void ReadConf()
{
	if (conf.path == NULL)
	{
		printf("未正确设置配置文件，退出\n");
		exit(1);
	}
	if (strlen(conf.path) == 0) {
		printf("未正确设置配置文件，退出\n");
		exit(1);
	}
	Config* pConfig = new Config();
	try {
		pConfig->readFile(conf.path);
		string db, server, username, pass, zhibao, dbpub;
		int port;
		if (!pConfig->lookupValue("database.dbname", db)) {
			db = "mycar";
		}
		if (!pConfig->lookupValue("database.zhibao", zhibao)) {
			zhibao = "zhibao";
		}
		if (!pConfig->lookupValue("database.host", server)) {
			server = "localhost";
		}
		if (!pConfig->lookupValue("database.port", port)) {
			port = 3306;
		}
		if (!pConfig->lookupValue("database.username", username)) {
			username = "root";
		}
		if (!pConfig->lookupValue("database.password", pass)) {
			pass = "";
		}
		if (!pConfig->lookupValue("database.public", dbpub)) {
			dbpub = "dbpub";
		}
		conf.dbname = strdup(db.c_str());
		conf.dbhost = strdup(server.c_str());
		conf.dbpass = strdup(pass.c_str());
		conf.dbuser = strdup(username.c_str());
		conf.zbname = strdup(zhibao.c_str());
		conf.dbpub = strdup(dbpub.c_str());
		conf.dbport = port;

		if (pConfig->exists("soft")) {
			string type;
			int version;
			string sfile;
			Setting& setting = pConfig->lookup("soft");
			for (int i = 0; i < setting.getLength(); i++) {
				if (setting[i].lookupValue("type", type)) {
					if (type == "N900" && setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
						conf.m_n900_version = version;
						conf.n900_file = strdup(sfile.c_str());
					} else if (type == "G2O" && setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
						conf.m_g2o_version = version;
						conf.g2o_file = strdup(sfile.c_str());
					}
				}
			}
		}

		if (pConfig->exists("socket")) {
			string route;
			if (pConfig->lookupValue("socket.route", route)) {
				conf.unix_path = strdup(route.c_str());
				conf.pManager = new DBManager(conf.unix_path);
			}

		}

	}catch(ParseException &er) {

	} catch (FileIOException &er) {

	} catch (...) {

	}
	if (pConfig)
		delete pConfig;
	try {
		DBPool *pool = new DBPool(conf.dbname, conf.dbhost, conf.dbuser, conf.dbpass, conf.dbport);
		Connection *cp = pool->grab();
		if (cp) {
			if (!cp->thread_aware()) {
				return;
			}
			pool->release(cp);
		}
		conf.cpool = pool;
	} catch (mysqlpp::Exception &er) {
		debug(LOG_DEBUG, "Create pool error: %s", er.what());
	}

}

time_t get_start()
{
	return conf.start;
}

time_t get_mtime()
{
	return conf.mtime;
}

int get_n900_version()
{
	struct stat buf;
	if (stat(conf.path, &buf) < 0)
		return conf.m_n900_version;
	if (buf.st_mtime > conf.mtime) {
		Config *pConfig = new Config();
		try {
			pConfig->readFile(conf.path);
			if (pConfig->exists("soft")) {
				string type;
				int version;
				string sfile;
				Setting& setting = pConfig->lookup("soft");
				for (int i = 0; i < setting.getLength(); i++) {
					if (setting[i].lookupValue("type", type)) {
						if (type != "N900")
							continue;
						if (setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
							conf.m_n900_version = version;
							conf.mtime = buf.st_mtime;
							free(conf.n900_file);
							conf.n900_file = strdup(sfile.c_str());
						}
					}
				}
			}
		} catch (...) {
		}
		if (pConfig)
			delete pConfig;
	}
	return conf.m_n900_version;
}

int get_g2o_version()
{
	struct stat buf;
	if (stat(conf.path, &buf) < 0)
		return conf.m_g2o_version;
	if (buf.st_mtime > conf.mtime) {
		Config *pConfig = new Config();
		try {
			pConfig->readFile(conf.path);
			if (pConfig->exists("soft")) {
				string type;
				int version;
				string sfile;
				Setting& setting = pConfig->lookup("soft");
				for (int i = 0; i < setting.getLength(); i++) {
					if (setting[i].lookupValue("type", type)) {
						if (type != "G2O")
							continue;
						if (setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
							conf.m_g2o_version = version;
							conf.mtime = buf.st_mtime;
							free(conf.g2o_file);
							conf.g2o_file = strdup(sfile.c_str());
						}
					}
				}
			}
		} catch (...) {
		}
		if (pConfig)
			delete pConfig;

	}
	return conf.m_g2o_version;
}

char *get_g2o_file()
{
	if (conf.g2o_file == NULL)
		return NULL;

	struct stat buf;
	if (stat(conf.g2o_file, &buf) < 0)
		return NULL;
	if (stat(conf.path, &buf) < 0)
		return NULL;

	if (buf.st_mtime > conf.mtime) {
		Config *pConfig = new Config();
		try {
			pConfig->readFile(conf.path);
			if (pConfig->exists("soft")) {
				string type;
				int version;
				string sfile;
				Setting& setting = pConfig->lookup("soft");
				for (int i = 0; i < setting.getLength(); i++) {
					if (setting[i].lookupValue("type", type)) {
						if (type != "G2O")
							continue;
						if (setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
							conf.m_g2o_version = version;
							free(conf.g2o_file);
							conf.g2o_file = strdup(sfile.c_str());
							conf.mtime = buf.st_mtime;
						}
					}
				}
			}
		} catch (...) {
		}
		if (pConfig)
			delete pConfig;
	}
	return conf.g2o_file;
}

char *get_n900_file()
{
	if (conf.n900_file == NULL)
		return NULL;

	struct stat buf;
	if (stat(conf.n900_file, &buf) < 0)
		return NULL;

	if (stat(conf.path, &buf) < 0)
		return NULL;

	if (buf.st_mtime > conf.mtime) {
		Config *pConfig = new Config();
		try {
			pConfig->readFile(conf.path);
			if (pConfig->exists("soft")) {
				string type;
				int version;
				string sfile;
				Setting& setting = pConfig->lookup("soft");
				for (int i = 0; i < setting.getLength(); i++) {
					if (setting[i].lookupValue("type", type)) {
						if (type != "N900")
							continue;
						if (setting[i].lookupValue("version", version) && setting[i].lookupValue("file", sfile)) {
							conf.m_n900_version = version;
							free(conf.n900_file);
							conf.n900_file = strdup(sfile.c_str());
							conf.mtime = buf.st_mtime;
						}
					}
				}
			}
		} catch (...) {
		}
		if (pConfig)
			delete pConfig;
	}

	return conf.n900_file;
}
